import { Controller, useForm } from "react-hook-form";
import { Form } from "react-router";
import { getLocalTimeZone } from "@internationalized/date";
import { css } from "@emotion/react";

import {
  Button,
  DateField,
  DateInput,
  DateSegment,
  DateValue,
  Dialog,
  FieldError,
  Flex,
  Input,
  Label,
  Text,
  TextArea,
  TextField,
  View,
} from "@phoenix/components";
import {
  DialogCloseButton,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogTitleExtra,
} from "@phoenix/components/dialog";

export type APIKeyFormParams = {
  name: string;
  description: string | null;
  expiresAt: DateValue | null;
};

/**
 * A dialog that allows admin users to create a system API key.
 */
export function CreateAPIKeyDialog(props: {
  isCommitting: boolean;
  onSubmit: (data: APIKeyFormParams, onClose: () => void) => void;
  defaultName?: APIKeyFormParams["name"];
}) {
  const { isCommitting, onSubmit, defaultName } = props;
  const {
    control,
    handleSubmit,
    formState: { isDirty, isValid },
  } = useForm<APIKeyFormParams>({
    defaultValues: {
      name: defaultName ?? "New Key",
      description: "",
      expiresAt: null,
    },
  });

  return (
    <Dialog>
      {({ close }) => (
        <DialogContent>
          <DialogHeader>
            <DialogTitle>Create an API Key</DialogTitle>
            <DialogTitleExtra>
              <DialogCloseButton slot="close" />
            </DialogTitleExtra>
          </DialogHeader>
          <Form onSubmit={handleSubmit((data) => onSubmit(data, close))}>
            <View padding="size-200">
              <Controller
                name="name"
                control={control}
                rules={{
                  required: "System key name is required",
                }}
                render={({
                  field: { onChange, onBlur, value },
                  fieldState: { invalid, error },
                }) => (
                  <TextField
                    isInvalid={invalid}
                    onChange={onChange}
                    onBlur={onBlur}
                    value={value.toString()}
                    size="S"
                  >
                    <Label>Name</Label>
                    <Input />
                    {error?.message ? (
                      <FieldError>{error.message}</FieldError>
                    ) : (
                      <Text slot="description">A name to identify the key</Text>
                    )}
                  </TextField>
                )}
              />
              <Controller
                name="description"
                control={control}
                render={({
                  field: { onChange, onBlur, value },
                  fieldState: { invalid, error },
                }) => (
                  <TextField
                    isInvalid={invalid}
                    onChange={onChange}
                    onBlur={onBlur}
                    value={value?.toString()}
                    size="S"
                  >
                    <Label>Description</Label>
                    <TextArea />
                    {error?.message ? (
                      <FieldError>{error.message}</FieldError>
                    ) : (
                      <Text slot="description">
                        A description of the system key
                      </Text>
                    )}
                  </TextField>
                )}
              />
              <Controller
                name="expiresAt"
                control={control}
                rules={{
                  validate: (value) => {
                    if (
                      value &&
                      value.toDate(getLocalTimeZone()) < new Date()
                    ) {
                      return "Date must be in the future";
                    }
                    return true;
                  },
                }}
                render={({
                  field: { name, onChange, onBlur, value },
                  fieldState: { invalid, error },
                }) => (
                  <DateField
                    isInvalid={invalid}
                    onChange={onChange}
                    onBlur={onBlur}
                    value={value}
                    name={name}
                    granularity="minute"
                    css={css`
                      .react-aria-DateInput {
                        width: 100%;
                      }
                    `}
                  >
                    <Label>Expires At</Label>
                    <DateInput>
                      {(segment) => <DateSegment segment={segment} />}
                    </DateInput>
                    {error?.message ? (
                      <FieldError>{error.message}</FieldError>
                    ) : (
                      <Text slot="description">
                        {"The date at which the key will expire. Optional"}
                      </Text>
                    )}
                  </DateField>
                )}
              />
            </View>
            <View
              paddingStart="size-200"
              paddingEnd="size-200"
              paddingTop="size-100"
              paddingBottom="size-100"
              borderColor="dark"
              borderTopWidth="thin"
            >
              <Flex direction="row" gap="size-100" justifyContent="end">
                <Button
                  variant={isDirty ? "primary" : "default"}
                  type="submit"
                  size="S"
                  isDisabled={!isValid || isCommitting}
                >
                  {isCommitting ? "Creating..." : "Create Key"}
                </Button>
              </Flex>
            </View>
          </Form>
        </DialogContent>
      )}
    </Dialog>
  );
}
